package com.ky.tms.service.impl;

import com.alibaba.excel.EasyExcel;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ky.tms.entity.*;
import com.ky.tms.enums.BusTypeEnum;
import com.ky.tms.enums.OrderEnum;
import com.ky.tms.exception.PredictableException;
import com.ky.tms.mapper.*;
import com.ky.tms.service.ITmsOrderService;
import com.ky.tms.util.RequestContextHolderUtil;
import com.ky.tms.vo.*;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.exception.ExceptionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.DuplicateKeyException;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import java.math.BigDecimal;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.List;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author chengkaimao
 * @since 2020-03-24
 */
@Service
public class TmsOrderServiceImpl extends ServiceImpl<TmsOrderMapper, TmsOrder> implements ITmsOrderService {


    @Autowired
    private TmsOrderMapper tmsOrderMapper;

    @Autowired
    private TmsCostMapper tmsCostMapper;

    @Autowired
    private TmsCustomerMapper tmsCustomerMapper;

    @Autowired
    private TmsLinePriceMapper tmsLinePriceMapper;

    @Autowired
    private TmsLineMapper tmsLineMapper;

    @Override
    public IPage<EntryOrder> entryPage(String userName, TmsOrder tmsOrder, Long limit, Long pages) {
        IPage<EntryOrder> page = new Page(pages, limit);
        page.setRecords(tmsOrderMapper.entryPage(page, tmsOrder));
        return page;
    }

    @Override
    public IPage<TrackOrder> trackPage(String userName, TrackOrder trackOrder, Long limit, Long pages) {
        IPage<TrackOrder> page = new Page(pages, limit);
        trackOrder.setOrderId(limit);
        trackOrder.setCustomId((pages-1)*limit);
        page.setRecords(tmsOrderMapper.trackOrder(trackOrder));
        page.setTotal(tmsOrderMapper.trackOrderTotal(trackOrder));
        return page;
    }

    @Override
    public IPage<TmsOrder> splitPage(String userName, TmsOrder tmsOrder, Long limit, Long pages) {
        IPage<TmsOrder> page = new Page(pages, limit);
        List<TmsOrder> tmsOrders = tmsOrderMapper.splitPage(page, tmsOrder);
        for(TmsOrder order : tmsOrders){
            List<TmsOrder> orderChildren = tmsOrderMapper.splitChildren(order.getId());
            if(orderChildren.size() > 0){
                order.setChildren(orderChildren);
            }
        }
        page.setRecords(tmsOrders);
        return page;
    }

    @Override
    public IPage<TmsOrder> dispatchPage(String userName, TmsOrder tmsOrder, Long limit, Long pages) {
        IPage<TmsOrder> page = new Page(pages, limit);
        page.setRecords(tmsOrderMapper.dispatchPage(page, tmsOrder));
        return page;
    }

    @Override
    public IPage<TmsOrder> auditPage(String userName, TmsOrder tmsOrder, Long limit, Long pages) {

        IPage<TmsOrder> page = new Page(pages, limit);
        List<TmsOrder> tmsOrders = tmsOrderMapper.auditPage(page, tmsOrder);
        for(TmsOrder order : tmsOrders){
            List<TmsOrder> orderChildren = tmsOrderMapper.splitChildren(order.getId());
            BigDecimal pickFee = order.getPickFee() == null ? new BigDecimal("0.00") : order.getPickFee();
            BigDecimal arteryFee = order.getArteryFee() == null ? new BigDecimal("0.00") : order.getArteryFee();
            BigDecimal dropoffFee = order.getDropoffFee() == null ? new BigDecimal("0.00") : order.getDropoffFee();
            BigDecimal workoverFee = order.getWorkoverFee() == null ? new BigDecimal("0.00") : order.getWorkoverFee();
            BigDecimal loadupFee = order.getLoadupFee() == null ? new BigDecimal("0.00") : order.getLoadupFee();
            BigDecimal loadoffFee = order.getLoadoffFee() == null ? new BigDecimal("0.00") : order.getLoadoffFee();
            BigDecimal carFee = order.getCarFee() == null ? new BigDecimal("0.00") : order.getCarFee();
            BigDecimal fuelFee = order.getFuelFee() == null ? new BigDecimal("0.00") : order.getFuelFee();
            BigDecimal callbackFee = order.getCallbackFee() == null ? new BigDecimal("0.00") : order.getCallbackFee();
            BigDecimal escortinFee = order.getEscortinFee() == null ? new BigDecimal("0.00") : order.getEscortinFee();
            BigDecimal tipFee = order.getTipFee() == null ? new BigDecimal("0.00") : order.getTipFee();
            BigDecimal shuttleFee = order.getShuttleFee() == null ? new BigDecimal("0.00") : order.getShuttleFee();
            BigDecimal feeSum = order.getFeeSum();

            if(orderChildren.size() > 0){
                order.setChildren(orderChildren);
                for(TmsOrder oc : orderChildren){
                    BigDecimal pickFeeC = oc.getPickFee() == null ? new BigDecimal("0.00") : oc.getPickFee();
                    BigDecimal arteryFeeC = oc.getArteryFee() == null ? new BigDecimal("0.00") : oc.getArteryFee();
                    BigDecimal dropoffFeeC = oc.getDropoffFee() == null ? new BigDecimal("0.00") : oc.getDropoffFee();
                    BigDecimal workoverFeeC = oc.getWorkoverFee() == null ? new BigDecimal("0.00") : oc.getWorkoverFee();
                    BigDecimal loadupFeeC = oc.getLoadupFee() == null ? new BigDecimal("0.00") : oc.getLoadupFee();
                    BigDecimal loadoffFeeC = oc.getLoadoffFee() == null ? new BigDecimal("0.00") : oc.getLoadoffFee();
                    BigDecimal carFeeC = oc.getCarFee() == null ? new BigDecimal("0.00") : oc.getCarFee();
                    BigDecimal fuelFeeC = oc.getFuelFee() == null ? new BigDecimal("0.00") : oc.getFuelFee();
                    BigDecimal callbackFeeC = oc.getCallbackFee() == null ? new BigDecimal("0.00") : oc.getCallbackFee();
                    BigDecimal escortinFeeC = oc.getEscortinFee() == null ? new BigDecimal("0.00") : oc.getEscortinFee();
                    BigDecimal tipFeeC = oc.getTipFee() == null ? new BigDecimal("0.00") : oc.getTipFee();
                    BigDecimal shuttleFeeC = oc.getShuttleFee() == null ? new BigDecimal("0.00") : oc.getShuttleFee();
                    BigDecimal feeSumC = oc.getFeeSum();
                    pickFee = pickFee.add(pickFeeC);
                    arteryFee = arteryFee.add(arteryFeeC);
                    dropoffFee = dropoffFee.add(dropoffFeeC);
                    workoverFee = workoverFee.add(workoverFeeC);
                    loadupFee = loadupFee.add(loadupFeeC);
                    loadoffFee = loadoffFee.add(loadoffFeeC);
                    carFee = carFee.add(carFeeC);
                    fuelFee = fuelFee.add(fuelFeeC);
                    callbackFee = callbackFee.add(callbackFeeC);
                    escortinFee = escortinFee.add(escortinFeeC);
                    tipFee = tipFee.add(tipFeeC);
                    shuttleFee = shuttleFee.add(shuttleFeeC);
                    feeSum = feeSum.add(feeSumC);
                }
                order.setPickFee(pickFee);
                order.setArteryFee(arteryFee);
                order.setDropoffFee(dropoffFee);
                order.setWorkoverFee(workoverFee);
                order.setLoadupFee(loadupFee);
                order.setLoadoffFee(loadoffFee);
                order.setCarFee(carFee);
                order.setFuelFee(fuelFee);
                order.setCallbackFee(callbackFee);
                order.setEscortinFee(escortinFee);
                order.setTipFee(tipFee);
                order.setShuttleFee(shuttleFee);
                order.setFeeSum(feeSum);
            }
        }
        page.setRecords(tmsOrders);
        return page;
    }

    @Override
    public IPage<TmsOrder> invoicePage(String userName, TmsOrder tmsOrder, Long limit, Long pages) {
        IPage<TmsOrder> page = new Page(pages, limit);
        List<TmsOrder> tmsOrders = tmsOrderMapper.invoicePage(page, tmsOrder);
        page.setRecords(tmsOrders);
        return page;
    }

    @Override
    public IPage<OrderIncome> incomePage(String userNam, TmsOrder tmsOrder, Long limit, Long pages) {
        IPage<OrderIncome> page = new Page(pages, limit);
        List<OrderIncome> tmsOrders = tmsOrderMapper.incomePage(page, tmsOrder);
        page.setRecords(tmsOrders);
        return page;
    }

    @Override
    public IPage<OrderIncomeAudit> incomeAuditPage(String userNam, TmsOrder tmsOrder, Long limit, Long pages) {
        IPage<OrderIncomeAudit> page = new Page(pages, limit);
        List<OrderIncomeAudit> tmsOrders = tmsOrderMapper.incomeAuditPage(page, tmsOrder);
        page.setRecords(tmsOrders);
        return page;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void entryAdd(String userName, EntryOrder entryOrder) throws PredictableException{
        if(StringUtils.isEmpty(entryOrder.getLoadNo())){
            throw new PredictableException("LOAD号不能为空");
        }
        if(entryOrder.getCustomId()==null){
            throw new PredictableException(entryOrder.getLoadNo() + ": 客户信息有误！");
        }
        QueryWrapper<TmsLinePrice> wrapper = new QueryWrapper<>();
        wrapper.eq("line_id",entryOrder.getLineId());
        wrapper.eq("car_type_id",entryOrder.getCarTypeId());
        TmsLinePrice tmsLinePrice = tmsLinePriceMapper.selectOne(wrapper);

        TmsLine tmsLine = tmsLineMapper.selectById(entryOrder.getLineId());

        TmsOrder tmsOrder = new TmsOrder();
        TmsCost tmsCost = new TmsCost();
        LocalDateTime now = LocalDateTime.now();
        this.convertEntry(entryOrder,tmsOrder,tmsCost);
        tmsOrder.setStatus(OrderEnum.ENTRY.getValue());
        tmsOrder.setIsValid(1);
        tmsOrder.setCreateTime(now);
        tmsOrder.setLoadNo(tmsOrder.getLoadNo().trim().toUpperCase());
        tmsOrder.setCreateUser(userName);
        if(tmsLine!=null){
            tmsOrder.setLoadingFactory(tmsLine.getLineStart());
            tmsOrder.setLoadoffFactory(tmsLine.getLineEnd());
            tmsOrder.setLoadingPlace(tmsLine.getLoadingPlace());
            tmsOrder.setLoadoffPlace(tmsLine.getLoadoffPlace());
        }
        tmsOrderMapper.insert(tmsOrder);
        if(tmsLinePrice == null || tmsLinePrice.getPrice() == null){
            // throw new PredictableException(entryOrder.getLoadNo() + ": 线路合同价格错误，请运营主管确认！");
            tmsCost.setCarFee(new BigDecimal("0"));
        }else{
            if(entryOrder.getBusType().equals(BusTypeEnum.APPLY.getValue())){
                tmsCost.setCarFee(tmsLinePrice.getPrice().multiply(new BigDecimal("1.7")));
            }else{
                tmsCost.setCarFee(tmsLinePrice.getPrice());
            }
        }

        tmsCost.setIsValid(1);
        tmsCost.setCreateTime(now);
        tmsCost.setCreateUser(userName);
        tmsCost.setFeeType("in");
        tmsCost.setOrderIds(tmsOrder.getId().toString());
        tmsCost.setLoadNo(tmsOrder.getLoadNo());
        tmsCostMapper.insert(tmsCost);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void entryUpdate(String userName, EntryOrder entryOrder) throws PredictableException {
        QueryWrapper<TmsLinePrice> wrapper = new QueryWrapper<>();
        wrapper.eq("line_id",entryOrder.getLineId());
        wrapper.eq("car_type_id",entryOrder.getCarTypeId());
        TmsLinePrice tmsLinePrice = tmsLinePriceMapper.selectOne(wrapper);
        TmsLine tmsLine = tmsLineMapper.selectById(entryOrder.getLineId());
        TmsOrder tmsOrder = new TmsOrder();
        TmsCost tmsCost = new TmsCost();
        LocalDateTime now = LocalDateTime.now();
        this.convertEntry(entryOrder,tmsOrder,tmsCost);
        tmsOrder.setLoadNo(tmsOrder.getLoadNo().trim().toUpperCase());
        tmsOrder.setUpdateTime(now);
        tmsOrder.setUpdateUser(userName);
        tmsCost.setUpdateTime(now);
        tmsCost.setUpdateUser(userName);
        tmsOrder.setLoadingFactory(tmsLine.getLineStart());
        tmsOrder.setLoadoffFactory(tmsLine.getLineEnd());
        tmsOrder.setLoadingPlace(tmsLine.getLoadingPlace());
        tmsOrder.setLoadoffPlace(tmsLine.getLoadoffPlace());
        if(tmsLinePrice == null || tmsLinePrice.getPrice() == null){
            // throw new PredictableException(entryOrder.getLoadNo() + ": 线路合同价格错误，请运营主管确认！");
            tmsCost.setCarFee(new BigDecimal("0"));
        }else{
            if(entryOrder.getBusType().equals(BusTypeEnum.APPLY.getValue())){
                tmsCost.setCarFee(tmsLinePrice.getPrice().multiply(new BigDecimal("1.7")));
            }else{
                tmsCost.setCarFee(tmsLinePrice.getPrice());
            }
        }
        tmsOrderMapper.updateById(tmsOrder);
        tmsCostMapper.updateById(tmsCost);
    }

    @Override
    public int entrySubmit(String userName, List<Long> ids) {
        return tmsOrderMapper.entrySubmit(userName,LocalDateTime.now(),ids);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public int entryDel(String userName, List<Long> ids) {
        tmsCostMapper.delByLoadNo(userName,LocalDateTime.now(),ids);
        return tmsOrderMapper.entryDel(userName,LocalDateTime.now(),ids);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void splitSave(String userName, TmsOrder tmsOrder) throws PredictableException {
        LocalDateTime now = LocalDateTime.now();
        TmsOrder tOrder = tmsOrderMapper.selectById(tmsOrder.getId());
        if(!OrderEnum.SPLIT.getValue().equals(tOrder.getStatus())){
            throw new PredictableException("订单状态异常！");
        }
        Long version = tOrder.getVersion() == null ? 0 : tmsOrder.getVersion();
        tOrder.setVersion(version+1);
        tOrder.setStatus(OrderEnum.SPLITED.getValue());
        tOrder.setUpdateUser(userName);
        tOrder.setUpdateTime(now);
        tmsOrderMapper.updateById(tOrder);

        // tmsOrderMapper.delChildren(tmsOrder.getId());
        List<TmsOrder> children = tmsOrder.getChildren();
        if(children != null){
            for(TmsOrder order : tmsOrder.getChildren()){
                order.setDnNo(tOrder.getDnNo());
                order.setIsValid(1);
                order.setCreateUser(userName);
                order.setCreateTime(now);
                order.setStatus(OrderEnum.SPLITED.getValue());
                order.setCustomName(tOrder.getCustomName());
                order.setCustomId(tOrder.getCustomId());
                tmsOrderMapper.insert(order);
            }
        }

    }

    @Override
    public int splitDel(Long id) {
        return tmsOrderMapper.delChildren(id);
    }

    @Override
    public void invoice(String userName, List<Long> ids) throws PredictableException {
        this.tmsOrderMapper.invoice(userName,LocalDateTime.now(), ids);

    }

    @Override
    public void pay(String userName, List<Long> ids) throws PredictableException {
        this.tmsOrderMapper.pay(userName,LocalDateTime.now(), ids);
    }

    @Override
    public void trackPass(String userName, TrackOrder trackOrder) throws PredictableException {
        LocalDateTime now = LocalDateTime.now();
        TmsOrder tmsOrder = tmsOrderMapper.selectById(trackOrder.getOrderId());
        if(OrderEnum.LOAD_IN.getValue().equals(trackOrder.getStatus())){
            if(!OrderEnum.COST_AUDIT.getValue().equals((tmsOrder.getStatus()))) {
                throw new PredictableException("状态异常！");
            }
            tmsOrder.setStatus(OrderEnum.LOAD_IN.getValue());
            tmsOrder.setUpdateTime(now);
            tmsOrder.setUpdateUser(userName);
            tmsOrder.setRemark(trackOrder.getRemark());
            tmsOrderMapper.updateById(tmsOrder);
            return;
        }
        if(OrderEnum.LOAD_OFF.getValue().equals(trackOrder.getStatus())){
            if(!OrderEnum.LOAD_IN.getValue().equals((tmsOrder.getStatus()))) {
                throw new PredictableException("状态异常！");
            }
            tmsOrder.setStatus(OrderEnum.LOAD_OFF.getValue());
            tmsOrder.setUpdateTime(now);
            tmsOrder.setUpdateUser(userName);
            tmsOrder.setRemark(trackOrder.getRemark());
            tmsOrderMapper.updateById(tmsOrder);
            return;
        }
        if(OrderEnum.RECEIPT.getValue().equals(trackOrder.getStatus())){
            if(!OrderEnum.LOAD_OFF.getValue().equals((tmsOrder.getStatus()))) {
                throw new PredictableException("状态异常！");
            }

            tmsOrder.setStatus(OrderEnum.RECEIPT.getValue());
            tmsOrder.setUpdateTime(now);
            tmsOrder.setUpdateUser(userName);
            tmsOrder.setRemark(trackOrder.getRemark());
            tmsOrderMapper.updateById(tmsOrder);
            if(tmsOrder.getParentId() != null){
                QueryWrapper<TmsOrder> wrapper = new QueryWrapper<>();
                wrapper.eq("parent_id", tmsOrder.getParentId());
                wrapper.ne("status",OrderEnum.RECEIPT.getValue());
                wrapper.eq("is_valid", 1);
                List<TmsOrder> tmsOrders = tmsOrderMapper.selectList(wrapper);
                if(tmsOrders.size() == 0){
                    TmsOrder tmsOrder1 = new TmsOrder();
                    tmsOrder1.setStatus(OrderEnum.RECEIPT.getValue());
                    tmsOrder1.setUpdateTime(now);
                    tmsOrder1.setUpdateUser(userName);
                    tmsOrder1.setId(tmsOrder.getParentId());
                    tmsOrderMapper.updateById(tmsOrder1);
                }
            }
            return;
        }

        throw new PredictableException("状态异常！");
    }

    @Override
    public void trackReject(String userName, TrackOrder trackOrder) throws PredictableException {

        LocalDateTime now = LocalDateTime.now();
        TmsOrder tmsOrder = tmsOrderMapper.selectById(trackOrder.getOrderId());
        if(OrderEnum.COST_AUDIT.getValue().equals(trackOrder.getStatus())){
            if(!OrderEnum.LOAD_IN.getValue().equals((tmsOrder.getStatus()))) {
                throw new PredictableException("状态异常！");
            }
            tmsOrder.setStatus(OrderEnum.COST_AUDIT.getValue());
            tmsOrder.setUpdateTime(now);
            tmsOrder.setUpdateUser(userName);
            tmsOrderMapper.updateById(tmsOrder);
            return;
        }
        if(OrderEnum.LOAD_IN.getValue().equals(trackOrder.getStatus())){
            if(!OrderEnum.LOAD_OFF.getValue().equals((tmsOrder.getStatus()))) {
                throw new PredictableException("状态异常！");
            }
            tmsOrder.setStatus(OrderEnum.LOAD_IN.getValue());
            tmsOrder.setUpdateTime(now);
            tmsOrder.setUpdateUser(userName);
            tmsOrderMapper.updateById(tmsOrder);
            return;
        }
        /*if(OrderEnum.LOAD_OFF.getValue().equals(trackOrder.getStatus())){
            if(!OrderEnum.RECEIPT.getValue().equals((tmsOrder.getStatus()))) {
                throw new PredictableException("状态异常！");
            }
            tmsOrder.setStatus(OrderEnum.LOAD_OFF.getValue());
            tmsOrder.setUpdateTime(now);
            tmsOrder.setUpdateUser(userName);
            tmsOrderMapper.updateById(tmsOrder);
            return;
        }*/

        throw new PredictableException("状态异常！");
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void incomeSave(String userName, OrderIncome orderIncome) throws PredictableException {
        TmsOrder tmsOrder = tmsOrderMapper.selectById(orderIncome.getId());
        if(!OrderEnum.RECEIPT.getValue().equals(tmsOrder.getStatus())){
            throw new PredictableException("状态异常");
        }
        LocalDateTime now = LocalDateTime.now();
        TmsCost tmsCost = new TmsCost();
        tmsCost.setPickFee(orderIncome.getPickFee());
        tmsCost.setArteryFee(orderIncome.getArteryFee());
        tmsCost.setDropoffFee(orderIncome.getDropoffFee());
        tmsCost.setWorkoverFee(orderIncome.getWorkoverFee());
        tmsCost.setLoadupFee(orderIncome.getLoadupFee());
        tmsCost.setLoadoffFee(orderIncome.getLoadoffFee());
        tmsCost.setCarFee(orderIncome.getCarFee());
        tmsCost.setFuelFee(orderIncome.getFuelFee());
        tmsCost.setCallbackFee(orderIncome.getCallbackFee());
        tmsCost.setEscortinFee(orderIncome.getEscortinFee());
        tmsCost.setShuttleFee(orderIncome.getShuttleFee());
        tmsCost.setLoadNo(tmsOrder.getLoadNo());
        tmsCost.setUpdateUser(userName);
        tmsCost.setUpdateTime(now);
        QueryWrapper<TmsCost> wrapper = new QueryWrapper<>();
        wrapper.eq("load_no", tmsCost.getLoadNo());
        wrapper.eq("fee_type", "in");
        wrapper.eq("is_valid", 1);

        tmsCostMapper.update(tmsCost, wrapper);
        tmsOrder.setVPrice(orderIncome.getVPrice());
        tmsOrder.setWPrice(orderIncome.getWPrice());
        tmsOrderMapper.updateById(tmsOrder);
    }

    @Override
    public void incomeSubmit(String userName, List<Long> ids) throws PredictableException {
        QueryWrapper<TmsOrder> wrapper = new QueryWrapper<>();
        wrapper.eq("is_valid", 1);
        wrapper.in("id", ids);
        wrapper.ne("status", OrderEnum.RECEIPT.getValue());
        List<TmsOrder> tmsOrders = tmsOrderMapper.selectList(wrapper);
        if(tmsOrders.size()>0){
            throw new PredictableException("状态异常！");
        }
        QueryWrapper<TmsOrder> wrapperUp = new QueryWrapper<>();
        wrapperUp.eq("is_valid", 1);
        wrapperUp.in("id", ids);
        LocalDateTime now = LocalDateTime.now();
        TmsOrder tmsOrder = new TmsOrder();
        tmsOrder.setUpdateUser(userName);
        tmsOrder.setUpdateTime(now);
        tmsOrder.setStatus(OrderEnum.GATHERING_AUDIT.getValue());
        tmsOrderMapper.update(tmsOrder, wrapperUp);
    }

    @Override
    public void incomeAudit(String userName, List<Long> ids) throws PredictableException {
        QueryWrapper<TmsOrder> wrapper = new QueryWrapper<>();
        wrapper.eq("is_valid", 1);
        wrapper.in("id", ids);
        wrapper.ne("status", OrderEnum.GATHERING_AUDIT.getValue());
        List<TmsOrder> tmsOrders = tmsOrderMapper.selectList(wrapper);
        if(tmsOrders.size()>0){
            throw new PredictableException("状态异常！");
        }
        QueryWrapper<TmsOrder> wrapperUp = new QueryWrapper<>();
        wrapperUp.eq("is_valid", 1);
        wrapperUp.in("id", ids);
        LocalDateTime now = LocalDateTime.now();
        TmsOrder tmsOrder = new TmsOrder();
        tmsOrder.setUpdateUser(userName);
        tmsOrder.setUpdateTime(now);
        tmsOrder.setStatus(OrderEnum.GATHERING.getValue());
        tmsOrderMapper.update(tmsOrder, wrapperUp);
    }

    @Override
    public void incomeReject(String userName, List<Long> ids) throws PredictableException {
        QueryWrapper<TmsOrder> wrapper = new QueryWrapper<>();
        wrapper.eq("is_valid", 1);
        wrapper.in("id", ids);
        wrapper.ne("status", OrderEnum.GATHERING_AUDIT.getValue());
        List<TmsOrder> tmsOrders = tmsOrderMapper.selectList(wrapper);
        if(tmsOrders.size()>0){
            throw new PredictableException("状态异常！");
        }
        QueryWrapper<TmsOrder> wrapperUp = new QueryWrapper<>();
        wrapperUp.eq("is_valid", 1);
        wrapperUp.in("id", ids);
        LocalDateTime now = LocalDateTime.now();
        TmsOrder tmsOrder = new TmsOrder();
        tmsOrder.setUpdateUser(userName);
        tmsOrder.setUpdateTime(now);
        tmsOrder.setStatus(OrderEnum.RECEIPT.getValue());
        tmsOrderMapper.update(tmsOrder, wrapperUp);
    }

    @Override
    public void invoiceReject(Long id) throws PredictableException {
        TmsOrder order = tmsOrderMapper.selectById(id);
        if(!OrderEnum.GATHERING.getValue().equals(order.getStatus())){
            throw new PredictableException("状态异常！");
        }
        String userName = RequestContextHolderUtil.getUserName();
        order.setStatus(OrderEnum.GATHERING_AUDIT.getValue());
        order.setUpdateTime(LocalDateTime.now());
        order.setUpdateUser(userName);
        tmsOrderMapper.updateById(order);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void reportEntry(String userName, MultipartFile file) throws PredictableException {

        List<TmsCustomer> customers = this.customers();
        EntryOrder order = null;
        try{
            List<EntryOrder> list = EasyExcel.read(file.getInputStream()).head(EntryOrder.class).sheet().doReadSync();
            for(EntryOrder orderData : list){
                order = orderData;
                if(StringUtils.isEmpty(orderData.getLoadNo())){
                    throw new PredictableException("LOAD号不能为空！");
                }
                for(TmsCustomer tmsCustomer : customers){
                    if(tmsCustomer.getCustomerName().equals(orderData.getCustomName())){
                        orderData.setCustomId(tmsCustomer.getId());
                        break;
                    }
                }
                if(orderData.getCustomId() == null){
                    throw new PredictableException(orderData.getLoadNo() + ": 项目简称有误！");
                }

                String busType = "";
                for (BusTypeEnum e : BusTypeEnum.values()) {
                    if(e.getDesc().equals(orderData.getBusType())){
                        busType = e.getValue();
                        break;
                    }
                }
                if(StringUtils.isEmpty(busType)){
                    throw new PredictableException(orderData.getLoadNo() + ": 业务类型有误！");
                }
                orderData.setBusType(busType);

                orderData.setPickDate(LocalDate.parse(orderData.getPickDateStr()));
                orderData.setAogDate(LocalDate.parse(orderData.getAogDateStr()));
                this.entryAdd(userName,orderData);
            }
        }catch( PredictableException e ){
                throw e;
        }catch( DuplicateKeyException e){
            throw new PredictableException("LOAD号重复:" + order.getLoadNo());
        } catch (Exception e){
            e.printStackTrace();
            throw new PredictableException(ExceptionUtils.getStackTrace(e));
        }
    }

    @Override
    public List<TmsCustomer> customers() {
        QueryWrapper<TmsCustomer> wrapper = new QueryWrapper<>();
        wrapper.eq("is_valid", 1);
        return tmsCustomerMapper.selectList(wrapper);
    }

    @Override
    public int splitDelLn(String loadNo) {
        QueryWrapper<TmsOrder> wrapper = new QueryWrapper<>();
        wrapper.eq("status", OrderEnum.SPLIT.getValue());
        wrapper.eq("load_no", loadNo);
        return tmsOrderMapper.delete(wrapper);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void rollbackSplit(String userName, TmsOrder tmsOrder) throws PredictableException {
        LocalDateTime now = LocalDateTime.now();
        TmsOrder tOrder = tmsOrderMapper.selectById(tmsOrder.getId());
        if(!OrderEnum.SPLITED.getValue().equals(tOrder.getStatus())){
            throw new PredictableException("订单状态异常！");
        }
        List<TmsOrder> orderChildren = tmsOrderMapper.splitChildren(tmsOrder.getId());
        for (TmsOrder order : orderChildren){
            if(!OrderEnum.SPLITED.getValue().equals(order.getStatus())){
                throw new PredictableException("订单状态异常！");
            }
        }
        tmsOrder.setUpdateUser(userName);
        tmsOrder.setUpdateTime(now);
        tmsOrder.setStatus(OrderEnum.SPLIT.getValue());
        tmsOrderMapper.updateById(tmsOrder);
        tmsOrderMapper.delChildren(tmsOrder.getId());
    }

    @Override
    public void auditOrder(String userName, TmsOrder tmsOrder) throws PredictableException {
        LocalDateTime now = LocalDateTime.now();
        // TmsOrder tOrder = tmsOrderMapper.selectById(tmsOrder.getId());
        List<TmsOrder> orderChildren = tmsOrderMapper.splitChildren(tmsOrder.getId());
        for(TmsOrder order : orderChildren){
            if(!OrderEnum.ORDER_AUDIT.getValue().equals(order.getStatus())){
                throw new PredictableException("订单状态异常！");
            }
        }
        if(OrderEnum.GATHERING.getValue().equals(tmsOrder.getStatus())){
            QueryWrapper<TmsOrder> queryWrapper = new QueryWrapper<>();
            queryWrapper.eq("is_valid", 1);
            queryWrapper.and(wrapper-> wrapper.eq("id", tmsOrder.getId()).or().eq("parent_id", tmsOrder.getId()));
            TmsOrder order = new TmsOrder();
            order.setStatus(OrderEnum.GATHERING.getValue());
            order.setUpdateTime(now);
            order.setUpdateUser(userName);
            tmsOrderMapper.update(order,queryWrapper);
        }

        throw new PredictableException("订单状态异常！");

    }

    @Override
    public void splitReject(String userName, TmsOrder tmsOrder) throws PredictableException {
        LocalDateTime now = LocalDateTime.now();
        TmsOrder tOrder = tmsOrderMapper.selectById(tmsOrder.getId());
        if(!OrderEnum.SPLIT.getValue().equals(tOrder.getStatus())){
            throw new PredictableException("订单状态异常！");
        }
        TmsOrder order = new TmsOrder();
        order.setId(tmsOrder.getId());
        order.setStatus(OrderEnum.ENTRY.getValue());
        order.setUpdateUser(userName);
        order.setUpdateTime(now);
        order.setRejectCase(tmsOrder.getRejectCase());
        tmsOrderMapper.updateById(order);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void income(String userName, TmsOrder tmsOrder) throws PredictableException {

        LocalDateTime now = LocalDateTime.now();
        TmsOrder tOrder = tmsOrderMapper.selectById(tmsOrder.getId());
        if(tOrder.getParentId() == null){
            List<TmsOrder> orderChildren = tmsOrderMapper.splitChildren(tmsOrder.getId());
            for(TmsOrder order : orderChildren){
                if(!OrderEnum.ORDER_AUDIT.getValue().equals(order.getStatus())){
                    throw new PredictableException("订单状态异常！");
                }
            }
        }else{
            if(!OrderEnum.ORDER_AUDIT.getValue().equals(tOrder.getStatus())){
                throw new PredictableException("订单状态异常！");
            }
        }
        QueryWrapper<TmsOrder> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("id", tmsOrder.getId()).or().eq("parent_id", tmsOrder.getId());
        TmsOrder order = new TmsOrder();
        order.setStatus(OrderEnum.GATHERING.getValue());
        order.setUpdateTime(now);
        order.setUpdateUser(userName);
        tmsOrderMapper.update(order,queryWrapper);
        tOrder.setRealIncome(tmsOrder.getRealIncome());
        tOrder.setStatus(OrderEnum.GATHERING.getValue());
        tOrder.setUpdateTime(now);
        tOrder.setUpdateUser(userName);
        tmsOrderMapper.updateById(tOrder);
    }

    // 输单对象转订单及费用
    private void convertEntry (EntryOrder entryOrder, TmsOrder tmsOrder, TmsCost tmsCost){

        tmsOrder.setId(entryOrder.getOrderId());
        tmsOrder.setCustomId(entryOrder.getCustomId());
        tmsOrder.setCustomName(entryOrder.getCustomName());
        tmsOrder.setLoadNo(entryOrder.getLoadNo());
        tmsOrder.setStatus(entryOrder.getStatus());
        tmsOrder.setPickDate(entryOrder.getPickDate());
        tmsOrder.setAogDate(entryOrder.getAogDate());
        tmsOrder.setLine(entryOrder.getLine());
        tmsOrder.setLoadingPlace(entryOrder.getLoadingPlace());
        tmsOrder.setLoadoffPlace(entryOrder.getLoadoffPlace());
        tmsOrder.setBasePoint(entryOrder.getBasePoint());
        tmsOrder.setBusType(entryOrder.getBusType());
        tmsOrder.setCarType(entryOrder.getCarType());
        tmsOrder.setAmount(entryOrder.getAmount());
        tmsOrder.setVolume(entryOrder.getVolume());
        tmsOrder.setWeight(entryOrder.getWeight());
        tmsOrder.setVPrice(entryOrder.getVprice());
        tmsOrder.setWPrice(entryOrder.getWprice());
        tmsOrder.setRemark(entryOrder.getRemark());
        tmsOrder.setDnNo(entryOrder.getDnNo());
        tmsOrder.setLoadingFactory(entryOrder.getLoadingFactory());
        tmsOrder.setLoadoffFactory(entryOrder.getLoadoffFactory());

        tmsCost.setLoadNo(entryOrder.getLoadNo());
        tmsCost.setId(entryOrder.getCostId());
        tmsCost.setPickFee(entryOrder.getPickFee());
        tmsCost.setArteryFee(entryOrder.getArteryFee());
        tmsCost.setDropoffFee(entryOrder.getDropoffFee());
        tmsCost.setWorkoverFee(entryOrder.getWorkoverFee());
        tmsCost.setLoadupFee(entryOrder.getLoadupFee());
        tmsCost.setLoadoffFee(entryOrder.getLoadoffFee());
        tmsCost.setCarFee(entryOrder.getCarFee());
        tmsCost.setFuelFee(entryOrder.getFuelFee());
        tmsCost.setCallbackFee(entryOrder.getCallbackFee());
        tmsCost.setEscortinFee(entryOrder.getEscortinFee());
        tmsCost.setTipFee(entryOrder.getTipFee());
        tmsCost.setShuttleFee(entryOrder.getShuttleFee());
    }
}
